#include"mystdio.h"
#include<stdlib.h>
#include<string.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h>

MYFILE* my_fopen(const char* filename, const char* mode)
{
    //打开文件创建FILE对象
    int fd = -1;
    if(strcmp(mode,"r"))
    {
        //以读的形式打开
        fd = open(filename , O_RDONLY);
    }
    else if(strcmp(mode,"w"))//以写的形式打开
    {
        fd = open(filename , O_CREAT | 0_WRONLY|O_TRUNC , UMASK);
    }
    else if(strcmp(mode,"a"))//以追加的形式打开
    {
        fd = open(filename , O_CREAT | O_WRONLY | O_APPEND, UMASK);
    }
    else if(strcmp(mode ,"a+"))
    {
        fd = open(filename , O_CREAT | O_RDWR | O_APPEND, UMASK);
    }
    else
    {
    }

    //如果到了此处fd 为-1 ，说明打开文件失败
    if(fd == -1) return NULL;

    //创建MYFILE对象
    MYFILE* fp = (MYFILE*)malloc(sizeof(MYFILE));
    if(fp==NULL) return NULL;
    //处理数据
    fp->fileno = fd;//文件描述符
    fp->flag = FLUSH_LINE;//行刷新
    fp->curr = 0;//当前大小
    fp->cap = SIZE;//容量
    fp->outbuffer[0]=0;//初始化输出缓冲区
    //返回MYFILE 指针
    return fp;
}

//刷新的核心代码
static void my_fflush_core(MYFILE* fp , int force)
{
    //输出缓冲区中没有数据就不进行刷新
    if(fp->curr<=0) return;
    //强制刷新
    if(force == FORCE)
    {
        //直接调用系统接口
        write(fp->fileno, fp->outbuffer , fp->curr);
        fp->curr=0;//将MYFILE中的数据个数置为0
    }
    else
    {
        //符合条件的才可以进行刷新
        if((fp->flag & FLUSH_LINE) && fp->outbuffer[fp->curr-1] =='\n')//符合行刷新的条件
        {
            //开始刷新
            write(fp->fileno,fp->outbuffer , fp->curr);
            fp->curr = 0;
        }
        else if((fp->flag & FLUSH_FULL) && fp->curr == fp->cap)//满刷
        {
            write(fp->filrno , fp->outbuffer , fp->curr);
            fp->curr =0;
        }
        else
        {
        }
    }
}

//写入
int my_fwrite(const char* s , int size , MYFILE*fp)//FILE指针中有mode
{
    //fwrite 的本质是拷贝
    memcpy(fp->outbuffer+fp->curr , s , size);
    fp->curr+=size;
    my_fflush_core(fp,NORMAL);
    return size;
}

void my_fflush(MYFILE* fp)
{
    my_fflush_core(fp,FORCE);
}

void my_fclose(MYFILE* fp)//传递FILE指针，其中有文件描述符
{
    if(fp->fileno>=0}//需要进行刷新
    {
        my_fflush(fp);
        fsync(fp->fileno);//刷新到外设上
        close(fp->fileno):
        free(fp);
    }
}
